#include "stdafx.h"
#include "net/SocketStream.hpp"
#include "net/StreamSocketImpl.hpp"

NET_NAMESPACE_BEGIN

CSocketStreamBuf::CSocketStreamBuf(const CSocket& socket) 
	: BufferedBidirectionalStreamBuf(STREAM_BUFFER_SIZE, std::ios::in | std::ios::out),
	m_pImpl(dynamic_cast<CStreamSocketImpl*>(socket.impl()))
{
	if (m_pImpl)
		m_pImpl->add(); 
	else
		throw InvalidArgumentException("Invalid or null SocketImpl passed to SocketStreamBuf");
}

CSocketStreamBuf::~CSocketStreamBuf()
{
	m_pImpl->release();
}

CStreamSocketImpl* CSocketStreamBuf::socketImpl() const
{
	return m_pImpl;
}

int CSocketStreamBuf::readFromDevice(char* buffer, std::streamsize length)
{
	return m_pImpl->receiveBytes(buffer, (int) length);
}

int CSocketStreamBuf::writeToDevice(const char* buffer, std::streamsize length)
{
	return m_pImpl->sendBytes(buffer, (int) length);
}



CSocketIOS::CSocketIOS(const CSocket& socket) : m_buf(socket)
{

}

CSocketIOS::~CSocketIOS()
{
	try
	{
		m_buf.sync();
	}
	catch (...)
	{
	}
}

CSocketStreamBuf* CSocketIOS::rdbuf()
{
	return &m_buf;
}

void CSocketIOS::close()
{
	m_buf.sync();
	m_buf.socketImpl()->close();
}

CStreamSocket CSocketIOS::socket() const
{
	return CStreamSocket(m_buf.socketImpl());
}



CSocketOutputStream::CSocketOutputStream(const CSocket& socket) : CSocketIOS(socket), std::ostream(&m_buf)
{

}

CSocketOutputStream::~CSocketOutputStream()
{

}


CSocketInputStream::CSocketInputStream(const CSocket& socket) : CSocketIOS(socket), std::istream(&m_buf)
{

}

CSocketInputStream::~CSocketInputStream()
{

}


CSocketStream::CSocketStream(const CSocket& socket) : CSocketIOS(socket), std::iostream(&m_buf)
{

}

CSocketStream::~CSocketStream()
{

}

NET_NAMESPACE_END
